package com.cngphone.AnFetion;

import java.util.ArrayList;
import java.util.Collections;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnFocusChangeListener;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnChildClickListener;

import com.cngphone.AnFetion.Fetion.SIPC.ReserveNotify;
import com.cngphone.AnFetion.tools.LogUtil;
import com.cngphone.AnFetion.tools.SystemInfo;
import com.cngphone.AnFetion2.R;

public class FetionListFriends extends Activity implements IFriendInfoChanged {

    private class FetionGroupView extends LinearLayout {
    	private TextView textView;
        public FetionGroupView(Context ctx, LayoutInflater mInflater) {
            super(ctx);
            this.addView(mInflater.inflate(R.layout.expandable_group, null));
            textView = (TextView) findViewById(R.id.group_name);
        }
        public void setText (String text) {
        	textView.setText(text);
        }
	}

	private class FetionFriendAdapter extends BaseExpandableListAdapter {
        protected Activity context;
        private LayoutInflater mInflater;
        
        public void sort () {
			if (mBoundService == null || mBoundService.getReserveNotify() == null || 
					mBoundService.getFriendManager().getGroups() == null)
				return;
        	ArrayList<FetionGroup> groups = mBoundService.getFriendManager().getGroups();
        	for (FetionGroup group : groups) {
				Collections.sort(group.getBuddies());
			}
        }
        
        public FetionFriendAdapter (Activity context) {
        	this.context = context;
            mInflater = LayoutInflater.from(context);
            sort ();
        }

		@Override
		public Object getChild(int groupPosition, int childPosition) {
			if (mBoundService == null || mBoundService.getReserveNotify() == null || 
					mBoundService.getFriendManager().getGroups() == null)
				return null;
			FetionGroup group = mBoundService.getFriendManager().getGroups().get(groupPosition);
			if (group == null)
				return null;
			return group.getBuddies().get(childPosition);
		}

		@Override
		public long getChildId(int groupPosition, int childPosition) {
			return 0;
		}

		@Override
		public View getChildView(int groupPosition, int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
            FetionFriend friend = (FetionFriend)getChild(groupPosition, childPosition);
            if (friend == null)
            	return null;

            FetionFriendView view = (FetionFriendView) convertView;
            if (convertView == null) {
                view = new FetionFriendView(context, mInflater);
            }
            view.set(MiscUtil.getFriendIcon(friend), friend.toShortString(), friend.impresa);
            view.setChatting(friend.isChatting());
            if (friend.lastMessage != null) {
                view.setText(friend.lastMessage);
            }
            return view;
		}

		@Override
		public int getChildrenCount(int groupPosition) {
			if (mBoundService == null || mBoundService.getReserveNotify() == null || 
					mBoundService.getFriendManager().getGroups() == null)
				return 0;
			FetionGroup group = mBoundService.getFriendManager().getGroups().get(groupPosition);
			if (group == null)
				return 0;
			return group.getBuddies().size();
		}

		@Override
		public Object getGroup(int groupPosition) {
			if (mBoundService == null || mBoundService.getReserveNotify() == null || 
					mBoundService.getFriendManager().getGroups() == null)
				return null;
			return mBoundService.getFriendManager().getGroups().get(groupPosition);
		}

		@Override
		public int getGroupCount() {
			if (mBoundService == null || mBoundService.getReserveNotify() == null || 
					mBoundService.getFriendManager().getGroups() == null)
				return 0;
			return mBoundService.getFriendManager().getGroups().size();
		}

		@Override
		public long getGroupId(int groupPosition) {
			return 0;
		}

		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			FetionGroupView view = (FetionGroupView)convertView;
			if (view == null) {
				view = new FetionGroupView(context, mInflater);
			}
			FetionGroup group = (FetionGroup)getGroup(groupPosition);
			int onlineNum = 0;
			for (FetionFriend friend : group.getBuddies()) {
				if (friend.getOnlineStatusInt() == Settings.STATUS_ONLINE)
					onlineNum++;
			}
			if (group != null)
				view.setText(group.getName() + "(" + onlineNum + "/" + group.getBuddies().size() + ")");	
			return view;
		}

		@Override
		public boolean hasStableIds() {
			return false;
		}

		@Override
		public boolean isChildSelectable(int groupPosition, int childPosition) {
			return true;
		}

	}

	public static final int IMPORT_PHONE_REQUEST_ID = 10;

    protected static final String TAG = "FetionListFriends";
    protected FetionService mBoundService;
    protected boolean isClosing = false;
    FetionFriendAdapter adapter;
    private BroadcastReceiver changeReceiver = new FriendChangeReceiver();
    private ExpandableListView friendsList;
    private SelfView selfView;
    private TextView title;
    private AlertDialog sendDialog;
    // private FetionFriend currFriend = null;

    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            mBoundService = ((FetionService.LocalBinder) service).getService();
            mBoundService.setFetionListFriends(FetionListFriends.this); // Tiger. Add
            FriendManager friendManager = mBoundService.getFriendManager(); 
            if (friendManager != null)
            	friendManager.clearMessageNotify();
            reload();
        }

        @Override
        public void onServiceDisconnected(ComponentName className) {
            mBoundService = null;
        }
    };

    private class SelfView implements OnClickListener, OnFocusChangeListener {
        private ImageButton _btnAvatar;
        private ImageButton _btnIcon;
        private EditText _lblImpresa;

        public SelfView(View view) {
            _btnIcon = (ImageButton) view.findViewById(R.id.list_icon);
            _btnIcon.setOnClickListener(this);
            _btnAvatar = (ImageButton) view.findViewById(R.id.avatar);
            _btnAvatar.setOnClickListener(this);
            _lblImpresa = (EditText) view.findViewById(R.id.impresa);
            _lblImpresa.setOnFocusChangeListener(this);
        }

        public void set(int drawIcon, String text, String impresa) {
            _btnIcon.setImageResource(drawIcon);
            title.setText(text);
            _lblImpresa.setText(impresa);
        }

        @Override
        public void onClick(View v) {
            FetionFriend me = mBoundService.getMyself();
            if (v == _btnIcon) {
                AlertDialog dialog = MiscUtil.getSetStautsMenu(FetionListFriends.this, me);
                dialog.show();
            } else {
                Toast.makeText(FetionListFriends.this, me.toFullString(), Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onFocusChange(View view, boolean flag) {
            _lblImpresa.setTextColor(flag ? 0xff000000 : 0xffffffff);
            if (mBoundService == null)
            	return;
            final FetionFriend friend = mBoundService.getMyself();
            final String impresa = _lblImpresa.getText().toString();
            if (!flag && !impresa.equals(friend.impresa)) {
                if (!MiscUtil.checkIsOnline()) return;
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        if (mBoundService.setPersonalInfo(null, impresa)) {
                            friend.impresa = impresa;
                            refreshSelf();
                        } else {
                            Toast.makeText(FetionListFriends.this, "更新心情短语失败!", Toast.LENGTH_LONG).show();
                            _lblImpresa.setText(friend.impresa);
                        }
                    }

                });
            }
        }
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Settings.DEBUG) LogUtil.d(TAG, "create");

        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.fetionfriendslist);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);

        title = (TextView) findViewById(R.id.custom_title);

        friendsList = (ExpandableListView) findViewById(R.id.friends);
        selfView = new SelfView(findViewById(R.id.self));

        // 绑定服务
        this.bindService(MiscUtil.getFetionServiceIntent(this), mConnection, Context.BIND_AUTO_CREATE);
        IntentFilter filter = new IntentFilter(Settings.ACTION_FRIEND_CHANGE);
        filter.addAction(Settings.ACTION_RECEIVE_MESSAGE);
        filter.addAction(Settings.ACTION_SENT_INVITE_FAIL);
        this.registerReceiver(changeReceiver, filter);
    }

    void reload() {
        if (Settings.DEBUG) LogUtil.d(TAG, "reload");
        ReserveNotify notify = mBoundService.getReserveNotify();
        if (notify != null) notify.addFriendInfoChangedListener(FetionListFriends.this);

        adapter = new FetionFriendAdapter(FetionListFriends.this);
        friendsList.setAdapter(adapter);

        refreshSelf();

        OnFriendClick listener = new OnFriendClick();
        friendsList.setOnChildClickListener(listener);
        friendsList.setOnCreateContextMenuListener(listener);
    }

    public void onResume() {
        super.onResume();
        if (Settings.DEBUG) LogUtil.d(TAG, "resume " + adapter);
        if (adapter != null) Happened(null);
        isClosing = false;
        if (mBoundService != null && mBoundService.getReserveNotify() != null)
            mBoundService.getFriendManager().clearMessageNotify();
    }

    @Override
    protected void onDestroy() {
        releaseAll();
        super.onDestroy();
    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            finish();
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        int count = Settings.LIST_MENU.length;
        for (int i = 0; i < count; i++) {
            MenuItem item = menu.add(Menu.NONE, Settings.LIST_MENU_IDS[i], Menu.NONE, Settings.LIST_MENU[i]);
            if (Settings.LIST_MENU_ICONS[i] != -1)
            	item.setIcon(Settings.LIST_MENU_ICONS[i]);
        }
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // System.out.println(requestCode + ":" + resultCode + ":" + data);
        if (requestCode == IMPORT_PHONE_REQUEST_ID && resultCode == -1 && data != null && sendDialog != null) {
            Uri uri = data.getData();
            String mobile = MiscUtil.toMobile(MiscUtil.getMobile(this, uri));
            // System.out.println("=====" + mobile);
            if (mobile != null) ((TextView) sendDialog.findViewById(R.id.mobileNo)).setText(mobile);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case (Settings.MENU_ADD): {
                if (!MiscUtil.checkIsOnline()) return true;

                sendDialog = MiscUtil.getInviteDialog(this);
                sendDialog.show();
                // dialog.getCurrentFocus().
                return true;
            }
            case (Settings.MENU_FINISH): {
                AlertDialog dialog = new AlertDialog.Builder(FetionListFriends.this).setTitle("系统提示")
                        .setMessage("确定要退出吗？").setPositiveButton("确定", new DialogInterface.OnClickListener() {

                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                isClosing = true;
                                mBoundService.close();
                                finish();
                            }

                        }).setNegativeButton("取消", null).create();
                dialog.show();
                return true;
            }
            case (Settings.MENU_QUIT): {
                isClosing = true;
                mBoundService.close();
                startService(MiscUtil.getFetionServiceIntent(this));
                Intent intent = new Intent(getApplicationContext(), FetionLoginActivity.class);
                startActivityIfNeeded(intent, 0);
                finish();
                return true;
            }
            
            /* feedback */
            case (Settings.MENU_FEEDBACK): {
            	Uri mailUri = Uri.parse("mailto:anfetion@googlegroups.com");
            	Intent mail = new Intent(Intent.ACTION_SENDTO, mailUri);
            	
            	String body = "\n\n\n\n----do NOT del text below this----\n";
            	body += SystemInfo.getVersion(getApplicationContext()) + "\n";
            	body += SystemInfo.toStr() + "\n";

            	mail.putExtra(Intent.EXTRA_TEXT, body);
            	mail.putExtra(Intent.EXTRA_SUBJECT, 
            			      "FEEDBACK about AnFetion proj");
            	startActivity(mail); 
            	
            	break;
            }
            case (Settings.MENU_ABOUT): {
            	// TODO implement a real dialog.
            	startActivity(new Intent(getApplicationContext(),AboutMe.class));
            	break;
            }
            case (Settings.MENU_SETUP): {
            	startActivity(new Intent(getApplicationContext(),FetionPreferenceActivity.class));
            	break;
            }
        }
        return true;
    }

    protected class OnFriendClick implements OnChildClickListener, OnCreateContextMenuListener {

        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
            if (!MiscUtil.checkIsOnline()) return false;

            FetionFriend friend = (FetionFriend) parent.getExpandableListAdapter().getChild(groupPosition, childPosition);
            if (friend == null)
            	return false;
            if (friend.IsMobileNo && friend.type != Settings.TYPE_FRIEND) {
                Toast.makeText(FetionListFriends.this, "手机好友同意好友请求前无法向其发送短信", Toast.LENGTH_LONG).show();
                return true;
            }
            Intent intent = new Intent(FetionListFriends.this, SendSMSActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            intent.putExtra("uri", friend.Uri);

            startActivityIfNeeded(intent, 0);
            return true;
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo contextmenuinfo) {
            if (!MiscUtil.checkIsOnline()) return;

            ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) contextmenuinfo;
            final long packedPosition = info.packedPosition;
            final int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition);
            if (groupPosition < 0)
            	return;
            switch (ExpandableListView.getPackedPositionType(packedPosition)) {
            case ExpandableListView.PACKED_POSITION_TYPE_CHILD:
                final int childPosition = ExpandableListView.getPackedPositionChild(packedPosition);
                if (childPosition < 0)
                	return;
                final FetionFriend friend = (FetionFriend) adapter.getChild(groupPosition, childPosition);
                if (friend == null) return;
                OnMenuItemClickListener listener = new OnFriendMenuItemClickListener(friend);
                int count = Settings.FRIEND_MENU.length;
                for (int i = 0; i < count; i++) {
                    if (friend.type == Settings.TYPE_FRIEND && Settings.FRIEND_MENU_IDS[i] == Settings.MENU_REINVITE) {
                        continue;
                    }
                    MenuItem mi = menu.add(Menu.NONE, Settings.FRIEND_MENU_IDS[i], Menu.NONE,
                            Settings.FRIEND_MENU[i]);
                    mi.setOnMenuItemClickListener(listener);
                }
            	break;
            }
        }

    }

    private class OnFriendMenuItemClickListener implements OnMenuItemClickListener {
        private FetionFriend friend;

        public OnFriendMenuItemClickListener(FetionFriend friend) {
            super();
            this.friend = friend;
        }

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            switch (item.getItemId()) {
                case Settings.MENU_DELETE: {
                    if (!MiscUtil.checkIsOnline()) return true;

                    if (Settings.DEBUG) LogUtil.d(TAG, "delete" + friend);
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            boolean success = mBoundService.sendDelete(new FetionUri(friend.Uri), false);
                            if (Settings.DEBUG) LogUtil.i(TAG, "result: " + success);
                            if (success) {
                                Toast.makeText(FetionListFriends.this, "您已删除此好友", Toast.LENGTH_SHORT).show();
                                //mBoundService.getFriendsAndReserveNotify();
                                mBoundService.getFriendManager().removeFriend(friend.Uri);
                                MiscUtil.notifyFriendChange(FetionListFriends.this);
                            } else if (!success) {
                                Toast.makeText(FetionListFriends.this, "处理不成功, 请检查是否已经删除过此好友!",
                                        Toast.LENGTH_SHORT).show();
                            }
                        }

                    });
                    break;
                }
                case Settings.MENU_MODIFY: {
                    if (!MiscUtil.checkIsOnline()) return true;
                    if (false && MiscUtil.isIntentAvailable(FetionListFriends.this,
                            "org.freecoder.securesms.ENCRYPT_MSG")) {
                        Intent i = new Intent("org.freecoder.securesms.ENCRYPT_MSG");
                        i.putExtra("mobile", friend.mobile_no);
                        i.putExtra("msg", "test");
                        FetionListFriends.this.startActivityForResult(i, 123);
                    }
                    Toast.makeText(FetionListFriends.this, friend.toFullString(), Toast.LENGTH_LONG).show();
                    break;
                }
                case Settings.MENU_REINVITE: {
                    sendDialog = MiscUtil.getInviteDialog(FetionListFriends.this, friend);
                    sendDialog.show();
                    // dialog.getCurrentFocus().
                    break;
                }
            }
            return true;
        }

    }

    private class FetionFriendView extends RelativeLayout {
        private View view;
        private TextView _lblName;
        private ImageView _lblAvatar;
        private ImageView _lblIcon;
        private TextView _lblMessage;
        private TextView _lblImpresa;
        private RelativeLayout _layout;
        private Drawable back_bubble;
        private Drawable back_normal;
        private Drawable avatar;

        public FetionFriendView(Context ctx, LayoutInflater mInflater) {
            super(ctx);
            this.view = mInflater.inflate(R.layout.friend, null);
            _lblIcon = (ImageView) view.findViewById(R.id.list_icon);
            this.addView(view);
            _lblAvatar = (ImageView) view.findViewById(R.id.avatar);
            _lblName = (TextView) view.findViewById(R.id.list_name);
            _lblMessage = (TextView) view.findViewById(R.id.message);
            _lblImpresa = (TextView) view.findViewById(R.id.impresa);
            _layout = (RelativeLayout) view.findViewById(R.id.layout_content);
            back_bubble = ctx.getApplicationContext().getResources().getDrawable(R.drawable.im_bubble);
            back_normal = ctx.getApplicationContext().getResources().getDrawable(R.drawable.im_normal);
            back_normal.setAlpha(0);
            avatar = ctx.getApplicationContext().getResources().getDrawable(R.drawable.fetion);
            _lblAvatar.setImageDrawable(avatar);
        }

        public FetionFriendView set(int drawIcon, String text, String impresa) {
            _lblIcon.setImageResource(drawIcon);
            if (R.drawable.user_offline == drawIcon || R.drawable.mobilebuddy == drawIcon) {
                avatar.mutate().setColorFilter(MiscUtil.COLORFILTER_GRAWSCALE);
            } else {
                avatar.mutate().setColorFilter(MiscUtil.COLORFILTER_NORMAL);
            }
            _lblName.setText(text);
            _lblImpresa.setText(impresa);
            setChatting(false);
            return this;
        }
        
        public void setChatting(boolean chatting) {
        	if (chatting) {
                _lblImpresa.setVisibility(View.GONE);
                _layout.setBackgroundDrawable(back_bubble);
                _lblName.setTextColor(0xff000000);
        	} else {
                _lblImpresa.setVisibility(View.VISIBLE);
                _lblMessage.setVisibility(View.GONE);
                _layout.setBackgroundDrawable(back_normal);
                _lblName.setTextColor(0xffffffff);
        	}
        }

        public void setText(String text) {
        	setChatting(true);
            if (text != null) {
                _lblMessage.setVisibility(View.VISIBLE);
                _lblMessage.setText(text);
            }
        }

    }

    @Override
    public void Happened(FetionFriend friend) {
        runOnUiThread(new Runnable() {
            public void run() {
                if (adapter != null) adapter.sort();
                friendsList.invalidateViews();
                refreshSelf();
            }
        });

    }

    public void refreshSelf() {
        FetionFriend friend = mBoundService.getMyself();
        selfView.set(MiscUtil.getFriendIcon(friend), friend.getNickName() + " ("
                + friend.getOndlineStatusStr() + ")", friend.impresa);
    }

    private void releaseAll() {
        mBoundService.setFetionListFriends(null);
        mBoundService.getReserveNotify().removeFriendInfoChangedListener(FetionListFriends.this);
        unbindService(mConnection);
        unregisterReceiver(changeReceiver);
    }

    public void onDisconnectSrv() {
        if (isClosing) return;
        runOnUiThread(new Runnable() {
            public void run() {
                MiscUtil.getReconnectDialog(FetionListFriends.this).show();
            }
        });
    }

    private class FriendChangeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(final Context ctx, Intent intent) {
            final String action = intent.getAction();
            if (Settings.DEBUG) LogUtil.d(TAG, action);
            if (Settings.ACTION_RECEIVE_MESSAGE.equals(action)) {
                // Collections.sort(buddies);
                if (adapter != null) adapter.sort();
                friendsList.invalidateViews();
                // FetionListFriends.this.reload();
                return;
            }
            if (Settings.ACTION_FRIEND_CHANGE.equals(action)) {
                FetionListFriends.this.reload();
                return;
            }
            if (Settings.ACTION_SENT_INVITE_FAIL.equals(action)) {
                Toast.makeText(ctx.getApplicationContext(), "邀请发送失败, 请重新发送!", Toast.LENGTH_SHORT).show();
                return;
            }
        }
    }

}
